package com.ysd.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.ysd.dao.DatabaseVersionDao;
import com.ysd.lis.entity.SysParam;
import com.ysd.lis.entity.SysParamField;
import com.ysd.lis.entity.SysParamValue;
import com.ysd.lis.mapper.sys.SysParamFieldMapper;
import com.ysd.lis.mapper.sys.SysParamValueMapper;
import com.ysd.lis.request.SysParamFieldJson;
import com.ysd.lis.request.SysParamFieldValueDto;
import com.ysd.lis.request.SysParamParam;
import com.ysd.lis.service.SysParamFieldService;
import com.ysd.lis.service.SysParamValueService;
import com.ysd.service.DatabaseVersionService;
import com.ysd.util.ToolsUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import org.springframework.util.FileCopyUtils;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * <p>
 * cold_chain.t_user 服务实现类
 * </p>
 *
 * @author peng
 * @since 2024-07-23
 */
@Service
@Slf4j
public class DatabaseVersionServiceImpl implements DatabaseVersionService {


    /**
     * 设置数据库分页类型
     */
    @Value("${mybatis-plus.configuration.page-type}")
    private String pageType;

    @Autowired
    DatabaseVersionDao databaseVersionDao;
    @Autowired
    SysParamValueService sysParamValueService;
    @Override
    public void upgradeDatabase() {
        /*数据库版本号 databaseVersion*/
        String databaseVersion = "0";
        SysParamFieldValueDto sysParamFieldValueDto = null;
        try {
            SysParamParam sysp = new SysParamParam();
            sysp.setParamCode("xtxxcs");
            sysp.setField("databaseVersion");
            List<SysParamFieldValueDto> dbvList = sysParamValueService.findSysParamFieldAndValueListByCode(sysp);
            if (!dbvList.isEmpty()) {
                databaseVersion = dbvList.get(0).getValue();
                sysParamFieldValueDto = dbvList.get(0);
            }
        } catch (Exception e) {
            //TODO
            databaseVersion = "0";
        }
        Integer dbversion = Integer.valueOf(databaseVersion);
        String filePath = "";
        if (pageType.indexOf("oracle") >= 0){
            filePath = "update4orcl.sql";
        }else{
            filePath = "update.sql";
        }

        ClassPathResource cpr = null;
        FileInputStream fileInputStream = null;
        InputStreamReader read = null;
        BufferedReader bufferedReader = null;
        boolean run = true;

        try {
            String encoding = "UTF-8";
            cpr = new ClassPathResource(filePath);
            File file = cpr.getFile();
            if (file.isFile() && file.exists()) { //判断文件是否存在
                fileInputStream = new FileInputStream(file);
                read = new InputStreamReader(fileInputStream, encoding);//考虑到编码格式
                bufferedReader = new BufferedReader(read);
                String lineTxt = null;
                String strsql = "";
                int bb = 0;
                while ((lineTxt = bufferedReader.readLine()) != null) {
                    int index = this.sqlbb(lineTxt);
                    if (index < 0) {
                        throw new ArithmeticException(lineTxt);
                    } else if (index == 0) {
                        strsql = strsql + "\n" + lineTxt;
                    } else {
                        bb = index - 1;
                        if (bb > dbversion && bb <= 1000) {
                            if (ToolsUtils.isNotEmpty(strsql)) {
                                this.exesql(strsql, bb, sysParamFieldValueDto);
                            }
                        }
                        strsql = "";
                    }
                }
                if (bb + 1 > dbversion && bb + 1 <= 1000) {
                    if (ToolsUtils.isNotEmpty(strsql)) {
                        System.out.println(strsql);
                        this.exesql(strsql, bb + 1, sysParamFieldValueDto);
                    }
                }

                run = true;
            } else {
                log.error("找不到指定的升级文件");
                run = false;
            }
        } catch (Exception e) {
            log.error("读取升级文件内容出错：" + e.getMessage());
            run = false;
        } finally {
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (Exception ex) {
                    ;
                }
            }
            if (fileInputStream != null) {
                try {
                    fileInputStream.close();
                } catch (Exception ex) {
                    ;
                }
            }
            if (read != null) {
                try {
                    read.close();
                } catch (Exception ex) {
                    ;
                }
            }
            if (cpr != null) {
                cpr.exists();
            }
            if (run == false) {
                System.exit(0);
            }
        }



    }

    @Autowired
    SysParamFieldMapper sysParamFieldMapper;
    @Autowired
    SysParamFieldService sysParamFieldService;
    @Autowired
    SysParamValueMapper sysParamValueMapper;
    @Override
    public void xtcsDataAuto() {
        //先查询系统选项参数中是否存在xtxxcsAutoVersion
        MPJLambdaWrapper<SysParamField> queryWrapper = new MPJLambdaWrapper<>();
        queryWrapper.selectAll(SysParamField.class,"t")
                .innerJoin(SysParamField.class,"t2",p->p.eq(SysParamField::getId,SysParamField::getPid).eq(SysParamField::getDelFlag,0).eq(SysParamField::getGrade,0).eq(SysParamField::getCode,"01"))
                .innerJoin(SysParam.class,"t3", p->p.eq(SysParam::getId,SysParamField::getPid).eq(SysParam::getDelFlag,0).eq(SysParam::getCode,"xtxxcs"))
                .eq("T.DEL_FLAG",0)
                .eq("T.FIELD","xtxxcsAutoVersion");
        List<SysParamField> fieldList = sysParamFieldMapper.selectList(queryWrapper);
        if(ToolsUtils.isEmpty(fieldList)){
            //系统自动添加xtxxcsAutoVersion系统参数
            MPJLambdaWrapper<SysParamField> queryWrapper1 = new MPJLambdaWrapper<>();
            queryWrapper1.selectAll(SysParamField.class)
                    .innerJoin(SysParam.class,"t2", p->p.eq(SysParam::getId,SysParamField::getPid).eq(SysParam::getDelFlag,0).eq(SysParam::getCode,"xtxxcs"))
                    .eq(SysParamField::getDelFlag,0)
                    .eq(SysParamField::getCode,"01")
                    .eq(SysParamField::getGrade,0);
            List<SysParamField> fieldGroupList = sysParamFieldMapper.selectList(queryWrapper1);
            if(ToolsUtils.isNotEmpty(fieldGroupList)){
                for(SysParamField fieldGroup : fieldGroupList){
                    SysParamField addField = new SysParamField();
                    addField.setPid(fieldGroup.getId());
                    addField.setGrade(1);
                    addField.setCompType("input");
                    addField.setField("xtxxcsAutoVersion");
                    addField.setTitle("系统参数升级版本号");
                    addField.setCode("10");
                    addField.setSpan(24);
                    addField.setAlign("left");
                    addField.setTitleAlign("right");
                    addField.setTitleWidth("200px");
                    addField.setTitleColon(0);
                    addField.setTitleAsterisk(0);
                    addField.setTitleOverflow(1);
                    addField.setShowTitle(1);
                    addField.setVertical(0);
                    addField.setSeq(10);
                    addField.setOrgId(fieldGroup.getOrgId());
                    fieldList.add(addField);
                }
                sysParamFieldService.saveBatch(fieldList);
            }


        }
        List<SysParamValue> paramValueList = new ArrayList<>();

        //查询对应的值
        if(ToolsUtils.isNotEmpty(fieldList)){
            for(SysParamField field : fieldList){
                MPJLambdaWrapper<SysParamValue> queryWrapperValue = new MPJLambdaWrapper<>();
                queryWrapperValue.selectAll(SysParamValue.class)
                        .eq(SysParamValue::getFieldId,field.getId())
                        .eq(SysParamValue::getDelFlag,0);
                List<SysParamValue> valueList = sysParamValueMapper.selectList(queryWrapperValue);
                if(ToolsUtils.isEmpty(valueList)){
                    SysParamValue value = new SysParamValue();
                    value.setFieldId(field.getId());
                    value.setValue("0");
                    value.setOrgId(field.getOrgId());
                    value.setDataType("input");
                    value.setIsLocal(false);
                    sysParamValueMapper.insert(value);
                    paramValueList.add(value);
                }else {
                    paramValueList.add(valueList.get(0));
                }

            }


        }

        //读取文件
        String filePath = "xtcsDataAuto.json";
        List<SysParamFieldJson> sysParamFieldJsonList = new ArrayList<>();
        //读取文件内容获取json数据
        try {
            ClassPathResource cpr = new ClassPathResource(filePath);
            InputStream inputStream = cpr.getInputStream();
            byte[] bytes = FileCopyUtils.copyToByteArray(inputStream);
            String s = new String(bytes, StandardCharsets.UTF_8);

            ObjectMapper objectMapper = new ObjectMapper();
            //转成Map<String, Object> jsonData
            Map<String, Object> jsonData = JSON.parseObject(s, Map.class);
            Object xtcsValues = jsonData.get("xtcsValues");
            if (xtcsValues instanceof List) {
                //根据反射讲字段映射到SysParamField中
                for (Object obj : (List) xtcsValues) {
                    SysParamFieldJson fieldDto = objectMapper.convertValue(obj, SysParamFieldJson.class);
                    System.out.println(fieldDto);
                    sysParamFieldJsonList.add(fieldDto);
                }

            }
        } catch (Exception e) {
            log.error("读取 JSON 文件内容出错：" + e.getMessage());
        }

        if(ToolsUtils.isNotEmpty(sysParamFieldJsonList)){
            for(SysParamValue value : paramValueList){
                System.out.println(value.getValue());
                String value1 = value.getValue();
                String orgId = value.getOrgId();
                //当前版本号 转成int
                int valueInt = Integer.parseInt(value1);
                //获取newSysParamFieldJsonList中索引包含valueInt之后的数据
                //List<SysParamFieldJson> addSysParamFieldJsonList = sysParamFieldJsonList.subList(valueInt, sysParamFieldJsonList.size());
                //循环json
                Integer jInt = null;
                for(int i = 0; i < sysParamFieldJsonList.size(); i++){
                    if(i >= valueInt){
                        SysParamFieldJson sysParamFieldJson = sysParamFieldJsonList.get(i);
                        //先根据paramCode，paramGroupCode，field,当前组织机构查询是否存在该系统参数
                        MPJLambdaWrapper<SysParamField> queryWrapperField = new MPJLambdaWrapper<>();
                        queryWrapperField.selectAll(SysParamField.class,"t")
                                .innerJoin(SysParamField.class,"t2",p->p.eq(SysParamField::getId,SysParamField::getPid)
                                        .eq(SysParamField::getDelFlag,0)
                                        .eq(SysParamField::getGrade,0)
                                        .eq(SysParamField::getOrgId,orgId)
                                        .eq(SysParamField::getCode,sysParamFieldJson.getParamGroupCode()))
                                .innerJoin(SysParam.class,"t3", p->p.eq(SysParam::getId,SysParamField::getPid)
                                        .eq(SysParam::getDelFlag,0)
                                        .eq(SysParam::getOrgId,orgId)
                                        .eq(SysParam::getCode,sysParamFieldJson.getParamCode()))
                                .eq("T.DEL_FLAG",0)
                                .eq("T.FIELD",sysParamFieldJson.getField())
                                .eq("T.ORG_ID",orgId);
                        List<SysParamField> sysParamFields = sysParamFieldMapper.selectList(queryWrapperField);
                        if(ToolsUtils.isEmpty(sysParamFields)){
                            //添加
                            MPJLambdaWrapper<SysParamField> queryWrapper1 = new MPJLambdaWrapper<>();
                            queryWrapper1.selectAll(SysParamField.class)
                                    .innerJoin(SysParam.class,"t2", p->p.eq(SysParam::getId,SysParamField::getPid)
                                            .eq(SysParam::getDelFlag,0)
                                            .eq(SysParam::getOrgId,orgId)
                                            .eq(SysParam::getCode,sysParamFieldJson.getParamCode()))
                                    .eq(SysParamField::getDelFlag,0)
                                    .eq(SysParamField::getCode,sysParamFieldJson.getParamGroupCode())
                                    .eq(SysParamField::getGrade,0)
                                    .eq(SysParamField::getOrgId,orgId);
                            List<SysParamField> fieldGroupList = sysParamFieldMapper.selectList(queryWrapper1);
                            if(ToolsUtils.isNotEmpty(fieldGroupList)){
                                SysParamField sysfieldGroup = fieldGroupList.get(0);
                                SysParamField addField = new SysParamField();
                                BeanUtil.copyProperties(sysParamFieldJson,addField);
                                addField.setPid(sysfieldGroup.getId());
                                addField.setOrgId(orgId);
                                sysParamFieldMapper.insert(addField);
                            }

                        }
                        jInt = i;

                    }

                }
                if(ToolsUtils.isNotEmpty(jInt)){
                    value.setValue(jInt+1+"");
                    sysParamValueMapper.updateById(value);
                }

            }
        }

    }


    private int sqlbb(String str) {
        int re = 0;
        try {
            if (ToolsUtils.isNotEmpty(str) && str.length() >= 5) {
                String str3 = str.substring(0, 3);
                if ("--[".equals(str3)) {
                    int indexyb = str.indexOf("]");
                    if (indexyb > 0) {
                        String strbb = str.substring(3, indexyb);
                        re = Integer.valueOf(strbb);
                    }
                }
            }
        } catch (Exception ex) {
            re = -1;
        }
        return re;
    }

    private void exesql(String strsql, int bb, SysParamFieldValueDto paras22) {
        Map<String, Object> map = new HashMap();
        map.put("sql", strsql);
        databaseVersionDao.exe(map);
        if (!map.get("intre").toString().equals("0")) {
            throw new ArithmeticException("版本[" + (bb) + "]" + "Sql[" + strsql + "]" + map.get("strre").toString());
        } else {
            SysParamValue sysParamValue = new SysParamValue();
            sysParamValue.setId(paras22.getValueId());
            sysParamValue.setValue(String.valueOf(bb));
            sysParamValueService.updateById(sysParamValue);
            log.error("版本[" + bb + "]升级成功");
        }
    }
}
